package registnet.records.source;

import java.util.HashMap;
import java.util.List;

import registnet.records.Checklist;
import registnet.records.CourseTaken;
import registnet.records.Curriculum;
import registnet.records.CurriculumCourse;
import registnet.records.ICourse;
import registnet.records.PlanOfCoursework;
import registnet.records.Student;
import registnet.records.Transcript;
import resources.Constants;

public class ChecklistSource {

	private Student student;
	private Checklist checklist;
	
	public ChecklistSource(Student student){
		this.student = student;
		this.load();
	}
	
	
	public void load(){
		registnet.dao.Student DAOStudent = new registnet.dao.StudentPeer().getStudent(this.student.getStudentNumber());
		
		this.checklist = new Checklist(this.student);
	
		try{
			Curriculum curriculum = new CurriculumSource(DAOStudent.getCurriculum().getCurriculumCode()).getCurriculum();
			PlanOfCoursework planOfCoursework = new PlanOfCourseworkSource(this.student).getPlanOfCoursework();
			Transcript transcript = new TranscriptSource(this.student).getTranscript();
			Transcript tmpTranscript = transcript;
			List<CurriculumCourse> curriculumCourses = curriculum.getCourses();
			HashMap<String, ICourse> renamedToMap = new HashMap<String, ICourse>();
			for(int i=0; i<curriculumCourses.size(); i++){
				ICourse course = curriculumCourses.get(i);
				ICourse tmpCourse = null;
				
				tmpCourse = this.getPlanOfCoursework(planOfCoursework, course);
				if(tmpCourse != null){
					course = tmpCourse;
				}
				
				
				try{
					if(course.getCourseCode().equals("NSTP 1")){
						CourseTaken nstp = null;
						if (tmpTranscript.getCourseTaken("LTS 1") != null){
							nstp = (CourseTaken)tmpTranscript.getCourseTaken("LTS 1");
						}
						if (tmpTranscript.getCourseTaken("CWTS 1") != null){
							CourseTaken temp = (CourseTaken)tmpTranscript.getCourseTaken("CWTS 1");
							if(nstp != null){
								if (nstp.getYearTaken() < temp.getYearTaken() || (nstp.getYearTaken() == temp.getYearTaken() && nstp.getSemesterTaken() < temp.getSemesterTaken())){
									tmpTranscript.getCourses().remove(nstp);
									nstp = temp;									
								}
								else
									tmpTranscript.getCourses().remove(temp);
							}
							else{
								nstp = temp;
							}
						}
						if (tmpTranscript.getCourseTaken("ROTC 1") != null){
							CourseTaken temp = (CourseTaken)tmpTranscript.getCourseTaken("ROTC 1");
							if(nstp != null){
								if (nstp.getYearTaken() < temp.getYearTaken() || (nstp.getYearTaken() == temp.getYearTaken() && nstp.getSemesterTaken() < temp.getSemesterTaken())){
									tmpTranscript.getCourses().remove(nstp);
									nstp = temp;									
								}
								else
									tmpTranscript.getCourses().remove(temp);
							}
							else{
								nstp = temp;
							}
						}
						tmpCourse = nstp;
					}
					
					else if(course.getCourseCode().equals("NSTP 2")){
						CourseTaken nstp = null;
						if (tmpTranscript.getCourseTaken("LTS 2") != null){
							nstp = (CourseTaken)tmpTranscript.getCourseTaken("LTS 2");
						}
						if (tmpTranscript.getCourseTaken("CWTS 2") != null){
							CourseTaken temp = (CourseTaken)tmpTranscript.getCourseTaken("CWTS 2");
							if(nstp != null){
								if (nstp.getYearTaken() < temp.getYearTaken() || (nstp.getYearTaken() == temp.getYearTaken() && nstp.getSemesterTaken() < temp.getSemesterTaken())){
									tmpTranscript.getCourses().remove(nstp);
									nstp = temp;									
								}
								else
									tmpTranscript.getCourses().remove(temp);
							}
							else{
								nstp = temp;
							}
						}
						if (tmpTranscript.getCourseTaken("ROTC 2") != null){
							CourseTaken temp = (CourseTaken)tmpTranscript.getCourseTaken("ROTC 2");
							if(nstp != null){
								if (nstp.getYearTaken() < temp.getYearTaken() || (nstp.getYearTaken() == temp.getYearTaken() && nstp.getSemesterTaken() < temp.getSemesterTaken())){
									tmpTranscript.getCourses().remove(nstp);
									nstp = temp;									
								}
								else
									tmpTranscript.getCourses().remove(temp);
							}
							else{
								nstp = temp;
							}
						}
						tmpCourse = nstp;
					}
					
					else if(course.getCourseCode().equals("GE(AH)"))
						tmpCourse = (CourseTaken)tmpTranscript.getCourseTaken("(AH)");
					
					else if(course.getCourseCode().equals("GE(MST)"))
						tmpCourse = (CourseTaken)tmpTranscript.getCourseTaken("(MST)");
					
					else if(course.getCourseCode().equals("GE(SSP)"))
						tmpCourse = (CourseTaken)tmpTranscript.getCourseTaken("(SSP)");
					else
						tmpCourse = (CourseTaken)tmpTranscript.getCourseTaken(course.getCourseCode());
					
					if(tmpCourse != null){
						if (((CourseTaken)tmpCourse).getGrade() == Constants.MAP_GRADE_KEY.get("S") || ((CourseTaken)tmpCourse).getGrade() == Constants.MAP_GRADE_KEY.get("DRP.") || ((CourseTaken)tmpCourse).getGrade() == Constants.MAP_GRADE_KEY.get("U") || ((CourseTaken)tmpCourse).getGrade() == Constants.MAP_GRADE_KEY.get("5") || ((CourseTaken)tmpCourse).getGrade() == Constants.MAP_GRADE_KEY.get("INC."))
							((CourseTaken)tmpCourse).setGrade(tmpTranscript.getLatestGrade(tmpCourse));
					}
					
				}catch(NullPointerException e){}
				
				if(tmpCourse != null){
					if (tmpCourse.getCourseName().contains("(now ")){
						String renamedTo = tmpCourse.getCourseName().replace("(now ", "");
						int index = renamedTo.lastIndexOf(")");
						renamedTo = renamedTo.substring(0, index);
						if(!renamedToMap.containsKey(renamedTo)){
							renamedToMap.put(renamedTo, tmpCourse);
						}
					}
					
					tmpTranscript.getCourses().remove(tmpCourse);
					tmpCourse.setSemester(course.getSemester());
					tmpCourse.setYear(course.getYear());
					
					if (renamedToMap.containsKey(tmpCourse.getCourseCode())){
						tmpCourse.setSemester(renamedToMap.get(tmpCourse.getCourseCode()).getSemester());
						tmpCourse.setYear(renamedToMap.get(tmpCourse.getCourseCode()).getYear());
						this.checklist.getCourses().set(this.checklist.getCourses().indexOf(renamedToMap.get(tmpCourse.getCourseCode())), tmpCourse);
						i--;
					}
					else
						course = tmpCourse;
				}
				
				try{
					if (!renamedToMap.containsKey(tmpCourse.getCourseCode()))
						checklist.addCourse(tmpCourse);
				}catch(Exception e){
					checklist.addCourse(course);
				}
				
			}
		}catch(Exception e){
			e.printStackTrace();
		}
			
	}

	
	
	private ICourse getPlanOfCoursework(PlanOfCoursework poc, ICourse course){
		try{
			List<ICourse> courses = poc.getCourses().get(course.getCourseCode());
			for(int i=0; i<courses.size(); i++){
				ICourse ic = courses.get(i);
				if (ic.getSemester() == course.getSemester() && ic.getYear() == course.getYear()){
					poc.getCourses().get(course.getCourseCode()).remove(i);
					return ic;
				}
			}
			return null;
		}catch(Exception e){
			return null;
		}
	}
	
	
	public Checklist getChecklist(){
		return this.checklist;
	}

	
}
